package com.atguigu.stgy.common.util;


import com.atguigu.stgy.common.config.JwtProperties;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.SignatureException;

import java.util.Date;

public class JwtUtils {
    private JwtUtils(){

    }
    /*
        1、springboot项目启动时，会初始化spring容器
        2、启动类能够扫描到的、springboot自动配置中的组件类、组件类中通过@Bean标注方法的返回值都会注入到容器中
            springboot启动时： 也可以在spring提供的bean的生命周期方法(对象初始化后调用的) 不同阶段做不同的事情
                - 例如：JwtProperties的初始化
                    > JwtProperties没有加组件注解
                    > springboot启动类扫描到SystemUserServiceImpl
                        初始化SystemUserServiceImpl对象前，会先将它依赖的对象引入到容器中(@EnableConfigurationProperties(value = JwtProperties.class))
                        在SystemUserServiceImpl之前 容器会先初始化JwtProperties对象
                    > 初始化JwtProperties的时候： jvm加载JwtProperties是，static属性会初始化（引用类型默认值为null）
                        因为JwtProperties实现了InitializingBean接口
                        所以对象创建后，容器会立即调用JwtProperties的afterPropertiesSet方法
                        在afterPropertiesSet方法中 将成员属性值 赋值给了静态属性
                    > 最后：
                        访问springboot的接口时
                        controller、service都是容器中的对象
                        获取JwtProperties的静态属性时，已经初始化过了


        3、springboot项目启动成功时
            在组件类中可以从容器中装配其他的组件对象使用

     */
//    @Resource
//    JwtProperties jwtProperties;
    /*
        如何在工具类中使用容器中的配置对象
            1、将工具类注入到容器中
                    静态方法无法使用自动装配的属性
           2、配置常量类 可以在自己的属性值初始化后 将属性值设置给自己的静态属性
                工具类被组件类的业务方法使用时，容器已经初始化了

     */
    //封装jwt
    public static String buildToken(String username , Long id){
        return Jwts.builder()
                .setHeaderParam("alg", JwtProperties.ALG)
                .setHeaderParam("typ", JwtProperties.TYP)
                .claim("id", id)
                .claim("username", username)
                //设置授权过期时间为7天
                .setExpiration(new Date(System.currentTimeMillis() + JwtProperties.EXPIRE))
                .setSubject(JwtProperties.SUBJECT)
                .signWith(SignatureAlgorithm.HS256, JwtProperties.KEY)
                .compact();
    }
    //解析jwt
    public static Jws<Claims> parseToken(String token){
        return Jwts.parserBuilder()
                .setSigningKey(JwtProperties.KEY) //设置密钥
                .build() //构建解析器
                //解析载荷内容
                .parseClaimsJws(token);
    }

    public static boolean checkToken(String token) {
        try {
            Jwts.parserBuilder()
                    .setSigningKey(JwtProperties.KEY) //设置密钥
                    .build() //构建解析器
                    //解析载荷内容
                    .parseClaimsJws(token);
            //解析token：没有过期、签名正确、数据正常  表示登录状态正常
            return true;
        } catch (Exception e) {
//            throw new RuntimeException(e);
            //jwt解析失败
            return false;
        }
    }
}
